#include <QDateTime>
#include <QSettings>
#include <QPixmapCache>
#include <QInputDialog>
#include <QIcon>

#include "wishmasterapplication.h"
#include "paths.h"
#include "mimetypes.h"
#include "log.h"
#include "components/threadid.h"
#include "components/postid.h"
#include "boardparsers/parserfactory.h"
#include "chanagents/agentfactory.h"
#include "watermarking/watermarkgeneratorfactory.h"
#include "coding/codingmanager.h"
#include "spellcheck/spellcheckermanager.h"
#include "libwishmaster.h"
#include "notification/notificationmanager.h"
#include "sqlitethreadstorage.h"
#include "standardchanmanager.h"
#include "filterlist.h"
#include "filtertext.h"
#include "chanagents/standardagentfactory.h"
#include "dummythreadstorage.h"

namespace Wishmaster
{
	WishmasterApplication::WishmasterApplication(int& argc, char** argv) : QApplication(argc, argv),
		m_argc(argc), m_argv(argv), m_chanmanager(0)
	{
		m_agentFactory = new StandardAgentFactory();
	}

	WishmasterApplication::~WishmasterApplication()
	{
		if(m_agentFactory)
			delete m_agentFactory;
		if(m_chanmanager)
		{
			m_chanmanager->shutdown();
			delete m_chanmanager;
		}
	}

	bool WishmasterApplication::initialize()
	{
		initLogging();
		parseArgs(m_argc, m_argv);

		setOrganizationName("anonymous");
		setOrganizationDomain("2ch.ru");
		setApplicationName("wishmaster");
		setApplicationVersion("0.6.3");

		LibWishmaster::loadResources();
		setIcon();

		registerMetatypes();

		initSingletons();
		m_agentFactory->loadPlugins();

		QCoreApplication::addLibraryPath("plugins");

		QSettings settings;
		QPixmapCache::setCacheLimit(1024 * settings.value("interface/cachesize", 50).toUInt());

		installTranslator();

		if(!createAndShowMainWindow())
			return false;

		initChanManager();

		return true;
	}

	void WishmasterApplication::initChanManager()
	{
		QSettings settings;

                m_chanmanager = new Wishmaster::StandardChanManager(m_mainWindow, new SQLiteThreadStorage(Wishmaster::DefaultPath::storageRoot() + QDir::separator() + "threadstorage"));
		//m_chanmanager = new Wishmaster::StandardChanManager(m_mainWindow, new DummyThreadStorage(), new CookieStorage());
		m_mainWindow->setChanManager(m_chanmanager);
		m_chanmanager->initialize();
		FilterListPtr filterList = FilterListPtr(new FilterList());
		filterList->addPrototype(FilterPtr(new FilterText("prototype")));
		filterList->load(settings.value("filters").toStringList());
		m_chanmanager->setFilterList(filterList);
		connect(m_chanmanager, SIGNAL(chanListChanged(QStringList)), m_mainWindow, SLOT(chanListChanged(QStringList)));
		connect(m_chanmanager, SIGNAL(contentChanged(QString,QString)), m_mainWindow, SLOT(updateBoardIndex(QString,QString)));
		connect(m_chanmanager, SIGNAL(contentChanged(PostId,int)), m_mainWindow, SLOT(updateContent(PostId,int)));

		QString defaultPath = Wishmaster::DefaultPath::shareRoot() + QDir::separator() + "chans.xml";
		m_chanmanager->loadChanList(defaultPath, m_agentFactory);
	}

	bool WishmasterApplication::createAndShowMainWindow()
	{
		m_mainWindow = new MainWindow(0);
		if(!m_mainWindow->initialize())
			return false;

		m_mainWindow->show();
		return true;
	}

	void WishmasterApplication::initLogging()
	{
		QString logFilename = (Wishmaster::DefaultPath::storageRoot() + "/wishmaster.log");
		qsrand(QDateTime::currentDateTime().toTime_t());
		QDir root(DefaultPath::storageRoot());
		root.mkpath(".");
		setLogfile(qPrintable(logFilename));
		setLogLevel(llNormal);
	}

	void WishmasterApplication::parseArgs(int argc, char** argv)
	{
		QString debug = "--debug";
		for(int i = 1; i < argc; i++)
		{
			if(debug == argv[i])
				setLogLevel(llDebug);
		}
	}

	void WishmasterApplication::registerMetatypes()
	{
		qRegisterMetaType<PostId>("PostId");
		qRegisterMetaType<ThreadId>("ThreadId");
	}

	void WishmasterApplication::initSingletons()
	{
		new Wishmaster::MimeTypes();
		ParserFactory::loadPlugins();
		new WatermarkGeneratorFactory();
		new CodingManager();
		new SpellCheckerManager();
		new NotificationManager();
	}

	void WishmasterApplication::setIcon()
	{
		QPixmap anon;
		anon.load(":/images/anonymous.png");
		setWindowIcon(QIcon(anon));
	}


	void WishmasterApplication::installTranslator()
	{
		QSettings settings;
		QString language = settings.value("language").toString();
		if(language.isEmpty() || !m_translator.load(language, Wishmaster::DefaultPath::i18n()))
		{
			QDir dir(Wishmaster::DefaultPath::i18n());
			QFileInfoList translationFiles = dir.entryInfoList(QStringList("*.qm"));
			QStringList translations;
			foreach(QFileInfo info, translationFiles)
			{
				translations.append(info.baseName());
			}
			bool ok;
			if(translations.size() > 0)
			{
				language = QInputDialog::getItem(NULL, "Select language", "Select language", translations, 0, false, &ok);
				if(!ok)
					return;
				settings.setValue("language", language);
			}
		}
		else
		{
			m_translator.load(language, Wishmaster::DefaultPath::i18n());
			qApp->installTranslator(&m_translator);
		}
		return;
	}
}
